package com.ly.heart.service.king;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.erp.CommonUtil;
import com.ly.common.utils.erp.KingConstUtil;
import com.ly.heart.domain.KingFinanceTransferReceiptDetailEntity;
import com.ly.heart.domain.KingFinanceTransferReceiptEntity;
import com.ly.heart.domain.KingOrgEntity;
import com.ly.heart.domain.king.BaseChildBo;
import com.ly.heart.domain.king.transfer.TransferReceiptBo;
import com.ly.heart.domain.king.transfer.TransferReceiptDetailBo;
import com.ly.heart.domain.request.KingBaseSingleRequest;
import com.ly.heart.domain.response.KingBaseResponse;
import com.ly.heart.domain.response.KingBaseResponseError;
import com.ly.heart.domain.response.KingBaseResponseSuccessEntity;
import com.ly.heart.domain.vo.KingFinanceTransferReceiptVo;
import com.ly.heart.service.IKingFinanceTransferReceiptService;
import com.ly.heart.service.IKingOrgService;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.heart.util.KingCommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class TransferReceiptPushService {

    @Resource
    private IKingFinanceTransferReceiptService iKingFinanceTransferReceiptService;
    @Resource
    private IKingOrgService iKingOrgService;


    public void push (KingFinanceTransferReceiptEntity kingFinanceTransferReceiptEntity) {
        KingOrgEntity orgEntity = iKingOrgService.getOne ( new LambdaQueryWrapper<KingOrgEntity> ().eq ( KingOrgEntity :: getOrgId, CurrentUserUtil.getCompanyId () ).eq ( KingOrgEntity :: getIsDisabled, true ) );
        if ( orgEntity == null ) {
            throw new CustomException ( "请先至系统管理中配置金蝶账套！" );
        }
        IdentifyInfo identifyInfo = KingCommonUtil.getIdentifyInfo ( orgEntity );
        K3CloudApi client = new K3CloudApi ( identifyInfo );
        log.info ( "银行转账单调用金蝶下推->{}", kingFinanceTransferReceiptEntity );
        KingFinanceTransferReceiptVo vo = iKingFinanceTransferReceiptService.selectKingFinanceTransferReceiptEntityById ( kingFinanceTransferReceiptEntity.getId () );
        if ( vo == null || vo.getKingFinanceTransferReceiptEntity () == null ) {
            throw new CustomException ( "该银行转账单为空！" );
        }
        if ( vo.getKingFinanceTransferReceiptEntity ().getIsSend () == KingConstUtil.KING_DATA_IS_SEND_YES ) {
            throw new CustomException ( "该单据已推送金蝶，无需重复推送！" );
        }
        TransferReceiptBo bo = assembleTransfer ( vo );
        try {
            save ( bo, client );
            submit ( bo, client );
            audit ( bo, client );
            updateSendSuccess ( kingFinanceTransferReceiptEntity.getId () );
        } catch ( Exception e ) {
            e.printStackTrace ();
            throw new CustomException ( "银行转账单推送失败，请稍后重试！" );
        }
    }

    private void save (TransferReceiptBo bo, K3CloudApi client) throws Exception {
        KingBaseSingleRequest singleRequest = new KingBaseSingleRequest ();
        singleRequest.setModel ( bo );
        String s = JSONObject.toJSONString ( singleRequest );
        log.info ( "银行转账单转JSON->{}", s );
        String resultJson = client.save ( KingConstUtil.CN_BANKTRANSBILL, s );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "银行转账单-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.info ( "{} 推送成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "银行转账单-推送失败：【" + sb + "】" );
        }
    }

    private void submit (TransferReceiptBo bo, K3CloudApi client) throws Exception {
        List<String> strings = new ArrayList<> ();
        strings.add ( bo.getFBillNo () );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.submit ( KingConstUtil.CN_BANKTRANSBILL, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            //提交成功
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "银行转账单-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.error ( "{} 提交成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "银行转账单提交失败：【" + sb + "】" );
        }
    }

    private void audit (TransferReceiptBo bo, K3CloudApi client) throws Exception {
        List<String> strings = new ArrayList<> ();
        strings.add ( bo.getFBillNo () );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.audit ( KingConstUtil.CN_BANKTRANSBILL, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            //提交成功
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "银行转账单-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.error ( "{} 审核成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "银行转账单审核失败：【" + sb + "】" );
        }
    }

    private void updateSendSuccess (String id) {
        KingFinanceTransferReceiptEntity transferReceiptEntity = new KingFinanceTransferReceiptEntity ();
        transferReceiptEntity.setId ( id );
        transferReceiptEntity.setIsSend ( KingConstUtil.KING_DATA_IS_SEND_YES );
        boolean b = iKingFinanceTransferReceiptService.updateById ( transferReceiptEntity );
        if ( ! b ) {
            throw new CustomException ( "修改推送金蝶状态失败！" );
        }
    }

    private TransferReceiptBo assembleTransfer (KingFinanceTransferReceiptVo vo) {
        KingFinanceTransferReceiptEntity transferReceiptEntity = vo.getKingFinanceTransferReceiptEntity ();
        TransferReceiptBo bo = new TransferReceiptBo ();
        //1.基础
        bo.setFBillNo ( transferReceiptEntity.getBillNo () );
        //单据类型
        BaseChildBo billType = new BaseChildBo ().setFNumber ( transferReceiptEntity.getDocTypeCode () );
        bo.setFBillTypeID ( billType );
        //业务日期
        bo.setFDATE ( CommonUtil.getDateStrFormat ( transferReceiptEntity.getBusinessTime (), "yyyy-MM-dd" ) );
        //备注
        bo.setFCOMMENT ( transferReceiptEntity.getRemarks () );
        //汇率类型

        List<TransferReceiptDetailBo> transferReceiptDetailBos = assembleTransferDetail ( vo.getKingFinanceTransferReceiptDetailEntities () );
        bo.setFEntity ( transferReceiptDetailBos );
        return bo;
    }

    private List<TransferReceiptDetailBo> assembleTransferDetail (List<KingFinanceTransferReceiptDetailEntity> kingFinanceTransferReceiptDetailEntities) {
        List<TransferReceiptDetailBo> bos = new ArrayList<> ();
        kingFinanceTransferReceiptDetailEntities.forEach ( detail -> {
            TransferReceiptDetailBo bo = new TransferReceiptDetailBo ();
            //转入银行
            BaseChildBo inBankCode = new BaseChildBo ().setFNumber ( detail.getInBankCode () );
            bo.setFTOBANKID ( inBankCode );
            //转入账号
            BaseChildBo inBankNo = new BaseChildBo ().setFNumber ( detail.getInBankNo () );
            bo.setFTOBANKACNTID ( inBankNo );
            //转出银行
            BaseChildBo outBankCode = new BaseChildBo ().setFNumber ( detail.getOutBankCode () );
            bo.setFFROMBANKID ( outBankCode );
            //转出账号
            BaseChildBo outBankNo = new BaseChildBo ().setFNumber ( detail.getOutBankNo () );
            bo.setFFROMBANKACNTID ( outBankNo );
            //转入币别
            BaseChildBo inBankCurrency = new BaseChildBo ().setFNumber ( detail.getKingBaseCurrencyCode () );
            bo.setFINCURRENCYID ( inBankCurrency );
            //转出币别
            BaseChildBo outBankCurrency = new BaseChildBo ().setFNumber ( detail.getKingBaseCurrencyCode () );
            bo.setFOUTCURRENCYID ( outBankCurrency );
            //转入金额
            bo.setFAmount ( detail.getTransferInAmount () );
            //转出金额
            bo.setFTOTALAMOUNT ( detail.getTransferOutAmount () );
            //转入结算号
            bo.setFINSETTLENO ( detail.getSettlementInNumber () );
            //转出结算号
            bo.setFSETTLENO ( detail.getSettlementOutNumber () );
            //摘要
            bo.setFEXPLANATION ( detail.getAbstractDesc () );
            //付款方手续费
            bo.setFFEE ( detail.getPayFee () );
            //收款方手续费
            bo.setFRECEIVEFEE ( detail.getReceiptFee () );
            //入账类型
            bo.setFRuZhangType ( detail.getEntryType () );
            //付款交易时间
            bo.setFFinishTime ( CommonUtil.getDateStrFormat ( detail.getTradingTime (), "yyyy-MM-dd" ) );
            bos.add ( bo );
        } );
        return bos;
    }

}
